#include "StimDotCloud.h"

#include <Random.h>

CStimDotCloud::CStimDotCloud(const enum Stims::ObjType& eObjType_/* = Stims::GLpoint*/)
    :
CStimDot(Stims::Cloud, eObjType_) // set dot volume type and dot type
{
}

CStimDotCloud::~CStimDotCloud(void)
{
}


std::string CStimDotCloud::GetName()
{
    return std::string("Cloud, same N at each depth");
}

double CStimDotCloud::ComputeSlice(const double& dDepth_,const int& nIdx_)
{
    double h    = dDepth_*_dTanFOVy_2;
    double w    = dDepth_*_dTanFOVx_2; // == h * _dAspectRatio

    if (nIdx_!=-1)
    {
        _vHalfLengthZ[nIdx_]    = dDepth_;
        _vHalfLengthY[nIdx_]    = h;
        _vHalfLengthX[nIdx_]    = w;
    }

    return h * w * dDepth_ / 3.;
}

void CStimDotCloud::SamplePoint(const double& dRadiusZ_, CMatrix<double>& mPoint_)
{
    //// Generate point, we sample points directly into the frustum to double (in the case of ground) or triple (in the case of cloud) the chance of generating a valid point.
    //// The increase in chance offsets the extra computational load for each point (as checking whether a point is valid is not cheap either).
    //// Even when simply sampling inside the frustum, this more complicated method turns out to be faster
    //// We use inverse transform sampling to get a Z sample corresponding to a uniform density frustum. For documentation, see CreateUniformDotsIn3DFrustum in the PsychToolBox for MATLAB
    // Z
    mPoint_(2) = -pow (grng::_C01()*(pow(dRadiusZ_,3)-pow(_dNearPlane,3))+pow(_dNearPlane,3),1/3.); // transform to parabolar distribution (negate as depth position is a negative number)
    
    // Y
    mPoint_(1) = RandLim(mPoint_(2)*_dTanFOVy_2,-mPoint_(2)*_dTanFOVy_2);

    // X
    mPoint_(0) = RandLim(mPoint_(2)*_dTanFOVx_2,-mPoint_(2)*_dTanFOVx_2);
}